import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:imperius_insights/portal/state/indicator/indicator.dart';
import 'package:imperius_insights/treaty/dimensions.dart';
import 'package:imperius_insights/treaty/palette.dart';

import 'error.dart';

typedef WidgetBuilder<T> = Widget Function(
    BuildContext context, IndicatorState<T> indicatorState);

class PlaceableWidget<T> extends StatelessWidget {
  final IndicatorState<T> indicatorState;
  final WidgetBuilder errorWidgetBuilder;
  final WidgetBuilder loadingWidgetBuilder;
  final WidgetBuilder contentBuilder;

  PlaceableWidget(
      {@required this.indicatorState,
      @required this.errorWidgetBuilder,
      @required this.loadingWidgetBuilder,
      @required this.contentBuilder});

  @override
  Widget build(BuildContext context) {
    return Observer(builder: (_) {
      if (indicatorState.status == Status.untapped ||
          indicatorState.status == Status.loading) {
        return loadingWidgetBuilder(context, indicatorState);
      }
      if (indicatorState.status == Status.error) {
        return errorWidgetBuilder(context, indicatorState);
      }
      if (indicatorState.status == Status.completed) {
        return contentBuilder(context, indicatorState);
      }
      throw Exception(
          'unspecified the render for the unknown state of ${indicatorState.status}');
    });
  }
}

Widget makeIndicateWidget<T>(
    {@required
        IndicatorState<T> indicator,
    @required
        Function onRefresh,
    @required
        Widget Function(BuildContext context, IndicatorState<T> indicator)
            contentBuilder}) {
  return PlaceableWidget<T>(
      indicatorState: indicator,
      loadingWidgetBuilder: (context, indicator) {
        return ConstrainedBox(
          constraints: BoxConstraints(minHeight: 300),
          child: Center(
              child: SpinKitWave(
                  color: palette.theme, size: layoutDimensions.indicatorSize)),
        );
      },
      errorWidgetBuilder: (_, indicatorState) {
        return NetworkErrorWidget(onRefresh);
      },
      contentBuilder: (context, indicator) {
        return contentBuilder(context, indicator);
      });
}
